//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using CommunityServer.Blogs.Components;
using CommunityServer.Components;
using System.Collections;
using System.Text;

namespace CommunityServer.SqlDataProvider
{
	/// <summary>
	/// Impliments Application Sepecific components of the BaseThreadQueryBuilder.BuildQuery method
	/// </summary>
	public class BlogThreadQueryBuilder : BaseThreadQueryBuilder
	{
		private BlogThreadQuery query;
		public BlogThreadQueryBuilder(ThreadQuery query, string databaseOwner): base(query, databaseOwner)
		{
			this.query = (BlogThreadQuery)query;
		}

		#region QueryBulder Overrides

		/// <summary>
		/// ORDER BY, HAVING and GROUP BY objects appended after the WHERE clause
		/// </summary>
        protected override void ApplySort()
        {
            // Add group by and having if necessary, then order by
            if(query.UncategorizedOnly)
            {
                sb.Append(" group by T.ThreadID, P.PostDate");
                sb.Append(" having count(PC.CategoryID) = 0");
            }

            switch (query.SortBy) {
                case BlogThreadSortBy.MostViewed:
                    sb.Append(" Order by P.TotalViews");
                    break;

                case BlogThreadSortBy.MostComments:
                    sb.Append(" Order by TotalReplies");
                    break;

                default:
                    sb.Append(" Order by P.PostDate");
                    break;

            }

            if(query.SortOrder == SortOrder.Ascending)
            {
                sb.Append(" asc ");
            }
            else
            {
                sb.Append(" desc ");
            }


        }

		/// <summary>
		/// WHERE clause element to filter by date ranges
		/// </summary>
		protected override void ApplyDateFilter()
		{
			//Do we care if the post has been publshied
			if(query.PublishedFilter != BlogPostPublishedFilter.All)
			{
				sb.AppendFormat(" and P.IsApproved = {0} and P.PostDate <= getdate() ", (int)query.PublishedFilter);
			}

			//Do we care about dates?
			if(query.BlogThreadType != BlogThreadType.Recent && query.BlogThreadType != BlogThreadType.Category && query.BlogThreadType != BlogThreadType.Tags)
			{
				DateTime safeDate = SQLHelper.GetSafeSqlDateTime(query.DateFilter);
                if(query.BlogThreadType == BlogThreadType.Day) {
                    sb.AppendFormat(" and Day(P.UserTime) = {0} and Month(P.UserTime) = {1} and Year(P.UserTime) = {2} ",safeDate.Day,safeDate.Month,safeDate.Year);

                }
                else if(query.BlogThreadType == BlogThreadType.Month) {
                    sb.AppendFormat(" and (P.UserTime >= '{0}' and P.UserTime < '{1}') ",SQLHelper.GetSafeSqlDateTimeFormat(safeDate),SQLHelper.GetSafeSqlDateTimeFormat(safeDate.AddMonths(1)));
                }
                else if (query.SortBy == BlogThreadSortBy.MostComments) {
                    sb.AppendFormat(" and Day(P.UserTime) >= " + DateTime.Now.AddDays(-7) + " ");
                }
				else
				{
					sb.AppendFormat(" and Year(P.UserTime) = {0} ",safeDate.Year);
				}

			}
		}

		/// <summary>
		/// WHERE clause element to specify the valid IsApproved / PostDate values
		/// </summary>
		protected override void ApplyPublished()
		{
			//Do we care if the post has been publshied
			if(query.PublishedFilter != BlogPostPublishedFilter.All)
			{
				sb.AppendFormat(" and P.IsApproved = {0} and P.PostDate <= getdate() ", (int)query.PublishedFilter);
			}
		}

		/// <summary>
		/// WHERE clause element to speficy the ApplicationPostType to return (bitwise comparison)
		/// </summary>
		protected override void ApplyPostType()
		{

			sb.AppendFormat(" and P.ApplicationPostType & {0} <> 0 ", (int)query.BlogPostType);

			if(query.PostConfig != BlogPostConfig.Empty)
				sb.AppendFormat(" and P.PostConfiguration & {0} = {0} ",(int)query.PostConfig );

            switch(query.BlogMirrorDisplayType)
            {
                case BlogMirrorDisplayType.MirrorBlogsOnly:
                    sb.AppendFormat(" and P.PostConfiguration & {0} = {0} ",(int)BlogPostConfig.IsExternal );
                break;
                case BlogMirrorDisplayType.BlogsOnly:
                    sb.AppendFormat(" and P.PostConfiguration & {0} = 0 ",(int)BlogPostConfig.IsExternal );
                    break;
            }
            
             
		}

		/// <summary>
		/// WHERE clause elemenet to apply values set in the FilterKey
		/// The base only runs this if the key length is greater than zero
		/// </summary>
		protected override void ApplyFilterKey()
		{
			sb.AppendFormat(" and S.SectionID in ({0}) and S.SectionID = P.SectionID and S.ApplicationType = 1 ", query.FilterKey);
		}

        protected override string GetSectionIDList()
        {
            if (query.HasFilterByList)
            {
                StringBuilder list = new StringBuilder();
                foreach (Weblog b in query.FilterByList)
                {
                    if (list.Length > 0)
                        list.Append(",");

                    list.Append(b.SectionID);
                }

                return list.ToString();
            
            }

            return null;
        }

		#endregion

	}
}
